package cn.yunyichina.provider.register.service.impl;

import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.CacheService;
import cn.yunyichina.provider.framework.dubbo.service.HisifaceService;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.hisiface.register.*;
import cn.yunyichina.provider.register.constant.CacheConstant;
import cn.yunyichina.provider.register.utils.RegUtil;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.log.Log;
import cn.yunyichina.utils.log.constant.LogParamType;
import cn.yunyichina.utils.log.constant.LogScene;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.kafka.common.utils.SystemTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static cn.yunyichina.provider.register.constant.CacheConstant.CACHE_REGISTER_MODULE;

/**
 * Created by Administrator on 2016/12/1.
 */
@Service
public class RegDoctorServiceImpl {
    private Logger logger = LoggerFactory.getLogger(RegDoctorServiceImpl.class);



    /**
     * 号源信息查询 yyt.register.reg.info.list --> yyt.register.reg.doctor.source.list
     * @param data
     * @param sessionId
     * @return
     */
    public Response listRegDoctorSource(String data, String sessionId) {
        logger.info("listRegDoctorSource, request data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();

        RegisterInfoVo infoVo = JsonUtils.parseObject(data, RegisterInfoVo.class);

        String timeStr = "";

        String beginDate = infoVo.getBeginDate();
        String regType = RegUtil.getRegType(beginDate);
        String now = new SimpleDateFormat("HH:mm").format(new Date());

        long beginTime = System.currentTimeMillis();
        if(RegUtil.REG_TYPE_DUTY.equals(regType)){//当班挂号规则判断
            if(RegUtil.getRule(infoVo.getHospitalCode(),RegUtil.REG_TYPE,"1,2").indexOf(RegUtil.REG_TYPE_DUTY) < 0){
                response.setResultCodeAndMessage("-1",RegUtil.NO_ONDUTY_REG_MSG);
                return response;
            }
            String onDutyRegTime = RegUtil.getRule(infoVo.getHospitalCode(),RegUtil.ON_DUTY_REG_TIME,"08:00-18:00");
            if(StringUtils.isNotBlank(onDutyRegTime)){
                String[] onDutyRegTimes = onDutyRegTime.split("-");
                String onDutyRegStartT = onDutyRegTimes[0];
                if (now.compareTo(onDutyRegStartT) < 1) {
                    response.setResultCodeAndMessage("-1",RegUtil.NOT_ON_DUTY_REG_TIMESTART_MSG);
                    return response;
                }
                if(onDutyRegTimes.length > 1){
                    String onDutyRegEndT = onDutyRegTimes[1];
                    if(now.compareTo(onDutyRegEndT) >= 1){
                        response.setResultCodeAndMessage("-1",RegUtil.NOT_ON_DUTY_REG_TIMEEND_MSG);
                        return response;
                    }
                }
            }

        }else{
            //预约挂号规则判断
            if(RegUtil.getRule(infoVo.getHospitalCode(),RegUtil.REG_TYPE,"1,2").indexOf(RegUtil.REG_TYPE_APPOINTMENT) < 0){
                response.setResultCodeAndMessage("-1",RegUtil.NO_ON_APPOINTMENT_REG_MSG);
                return response;
            }
            // 判断是否已配置预约明天限制
            if(beginDate.equals(DateUtils.tomorrowDate())){
                String appointmentTomorrowEndTime = RegUtil.getRule(infoVo.getHospitalCode(),RegUtil.APPOINTMENT_TOMORROW_ENDTIME,"17:00");
                if(now.compareTo(appointmentTomorrowEndTime) >= 1){
                    response.setResultCodeAndMessage("-1",RegUtil.NOT_APPOINTMENT_TOMORROW_ENDTIME_MSG);
                    return response;
                }
            }
        }

        timeStr += "规则:" + (System.currentTimeMillis()-beginTime);
        beginTime = System.currentTimeMillis();

        String cacheKey = infoVo.getHospitalCode() + (StringUtils.isNotBlank(infoVo.getBranchCode())?":" + infoVo.getBranchCode() : "")
                + ":" + infoVo.getDeptCode() + ":" + infoVo.getBeginDate();
        String cacheValue = CacheService.getGlobalKey(CacheConstant.CACHE_REGISTER_MODULE, CacheConstant.CACHE_REGISTER_DOCTORSOURCE, cacheKey);
        timeStr += ";缓存:" + (System.currentTimeMillis()-beginTime);
        beginTime = System.currentTimeMillis();

        List<RegisterInfoVoResponse> sourceList ;
        if(StringUtils.isNotBlank(cacheValue)){
//            logger.info("listRegDoctorSource,缓存命中cacheValue={}",cacheValue);
            Log.i(LogScene.REGISTER_DOCTOR_SOURCE,"yyt.register.reg.doctor.source.list", LogParamType.NORMAL,infoVo.getHospitalCode(),"缓存命中cacheValue=" + cacheValue);
            sourceList = JsonUtils.parseArray(cacheValue,RegisterInfoVoResponse.class);
        }else{
            //缓存过期，查询his
            ResCommon<List<RegisterInfoVoResponse>> infoResponse = HisifaceService.getHisifaceClient().getRegisterInfo(infoVo);
            timeStr += ";查his:" + (System.currentTimeMillis()-beginTime);
            beginTime = System.currentTimeMillis();
//            logger.info("listRegDoctorSource,call hisiface getRegisterInfo,request={},response={}",
//                    JSONObject.toJSONString(infoVo),JSONObject.toJSONString(infoResponse));
            Log.i(LogScene.REGISTER_DOCTOR_SOURCE,"getRegisterInfo", LogParamType.REQUEST,infoVo.getHospitalCode(),JSONObject.toJSONString(infoVo));
            Log.i(LogScene.REGISTER_DOCTOR_SOURCE,"getRegisterInfo", LogParamType.RESPONSE,infoVo.getHospitalCode(),JSONObject.toJSONString(infoResponse));
            if (!ResCommon.SUCCESS_CODE.equals(infoResponse.getResultCode())) {
                response.setResultCodeAndMessage(infoResponse.getResultCode(),
                        "查询号源信息失败！");
                return response;
            }
            sourceList = infoResponse.getResult();
            if (!CollectionUtils.isEmpty(sourceList)) {
                try {
                    //号源存缓存
                    String ruleExpire = RegUtil.getRule(infoVo.getHospitalCode(), RegUtil.DOCTOR_SOURCE_CACHE_MINUTE, "3");
                    int expireTime = Integer.parseInt(ruleExpire) * 60;
                    if(expireTime > 0) {
                        CacheService.setGlobalKey(CacheConstant.CACHE_REGISTER_MODULE, CacheConstant.CACHE_REGISTER_DOCTORSOURCE, cacheKey,
                                JsonUtils.toJsonString(sourceList), expireTime);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    logger.info("设置号源缓存异常" +e.getMessage());
                }
            }
        }

        if (CollectionUtils.isEmpty(sourceList)) {
            response.setResultCodeAndMessage("6002", "暂无号源信息！");
            return response;
        } else {
            String isQueryDoctor = RegUtil.getRule(infoVo.getHospitalCode(), RegUtil.IS_QUERY_DOCTOR, "1");
            if("1".equals(isQueryDoctor)){
                for(RegisterInfoVoResponse sourceItem:sourceList) {
                    List<RegisterInfoItem> registerInfoList = sourceItem.getRegisterInfoItems();
                    for (RegisterInfoItem infoItem : registerInfoList) {
                        String findDoctor = "{\"code\":\"" + infoItem.getDoctorCode() + "\",\"hospitalCode\":\"" + infoVo.getHospitalCode() + "\"}";
    //                    String findDoctor = "{\"code\":\"" + "1743" + "\",\"hospitalCode\":\"" + "stszxyy" + "\"}";
                        Response doctorResponse = BaseService.callHumpFromInternal("yyt.base.doctor.find", findDoctor);
                        logger.info("listRegDoctorSource, yyt.base.doctor.find doctorResponse=" + JsonUtils.toJsonString(doctorResponse));
                        if ("0".equals(doctorResponse.getResultCode())) {
                            JSONObject result = JsonUtils.parseObject(doctorResponse.getResult(), JSONObject.class);
                            if (result != null) {
                                infoItem.setDoctorIntroduction(result.getString("disc"));
                                String img = result.getString("img");
                                if (img != null && img.startsWith("http")) {
                                    infoItem.setDoctorPicture(img);
                                }
                            }
                        }
                    }
                }
            }
            timeStr += ";医生信息：" + (System.currentTimeMillis()-beginTime);
            response.setResultCodeAndMessage("0",infoVo.getHospitalCode() + ":" + timeStr);
            response.setResult(JsonUtils.toJsonString(sourceList).replaceAll("register_info_items","register_info_list"));
        }
        return response;
    }

    /**
     * 医生分时信息查询接口 yyt.register.doctor.time.list --> yyt.register.reg.doctor.time.list
     * @param data
     * @param sessionId
     * @return
     */
    public Response listRegDoctorTime(String data, String sessionId) {
        logger.info("listRegDoctorTime, request data=" + data + ", sessionId=" + sessionId);
        Response response = new Response();

        RegisterDoctorTimeVo timeVo = JsonUtils.parseObject(data, RegisterDoctorTimeVo.class);

        /*************************************/
        String regType = RegUtil.getRegType(timeVo.getScheduleDate());
        String now = new SimpleDateFormat("HH:mm").format(new Date());
        if(RegUtil.REG_TYPE_DUTY.equals(regType)){//当班挂号规则判断
            if(RegUtil.getRule(timeVo.getHospitalCode(),RegUtil.REG_TYPE,"1,2").indexOf(RegUtil.REG_TYPE_DUTY) < 0){
                response.setResultCodeAndMessage("-1",RegUtil.NO_ONDUTY_REG_MSG);
                return response;
            }
            String onDutyRegTime = RegUtil.getRule(timeVo.getHospitalCode(),RegUtil.ON_DUTY_REG_TIME,"08:00-18:00");
            if(StringUtils.isNotBlank(onDutyRegTime)){
                String[] onDutyRegTimes = onDutyRegTime.split("-");
                String onDutyRegStartT = onDutyRegTimes[0];
                if (now.compareTo(onDutyRegStartT) < 1) {
                    response.setResultCodeAndMessage("-1",RegUtil.NOT_ON_DUTY_REG_TIMESTART_MSG);
                    return response;
                }
                if(onDutyRegTimes.length > 1){
                    String onDutyRegEndT = onDutyRegTimes[1];
                    if(now.compareTo(onDutyRegEndT) >= 1){
                        response.setResultCodeAndMessage("-1",RegUtil.NOT_ON_DUTY_REG_TIMEEND_MSG);
                        return response;
                    }
                }
            }

        }else{
            //预约挂号规则判断
            if(RegUtil.getRule(timeVo.getHospitalCode(),RegUtil.REG_TYPE,"1,2").indexOf(RegUtil.REG_TYPE_APPOINTMENT) < 0){
                response.setResultCodeAndMessage("-1",RegUtil.NO_ON_APPOINTMENT_REG_MSG);
                return response;
            }
            // 判断是否已配置预约明天限制
            if(timeVo.getScheduleDate().equals(DateUtils.tomorrowDate())){
                String appointmentTomorrowEndTime = RegUtil.getRule(timeVo.getHospitalCode(),RegUtil.APPOINTMENT_TOMORROW_ENDTIME,"17:00");
                if(now.compareTo(appointmentTomorrowEndTime) >= 1){
                    response.setResultCodeAndMessage("-1",RegUtil.NOT_APPOINTMENT_TOMORROW_ENDTIME_MSG);
                    return response;
                }
            }
        }
        /**********************规则判断end***************/

        ResCommon<List<RegisterDoctorTimeVoResponse>> timeResponse = HisifaceService.getHisifaceClient().getRegisterDoctorTime(timeVo);
//        logger.info("listRegDoctorTime,call hisiface getRegisterDoctorTime, request={},response={}",
//                JSONObject.toJSONString(timeVo),JSONObject.toJSONString(timeResponse));
        Log.i(LogScene.REGISTER_DOCTOR_SOURCE,"getRegisterDoctorTime", LogParamType.REQUEST,timeVo.getHospitalCode(),JSONObject.toJSONString(timeVo));
        Log.i(LogScene.REGISTER_DOCTOR_SOURCE,"getRegisterDoctorTime", LogParamType.RESPONSE,timeVo.getHospitalCode(),JSONObject.toJSONString(timeResponse));

        if (!ResCommon.SUCCESS_CODE.equals(timeResponse.getResultCode())) {
            response.setResultCodeAndMessage(timeResponse.getResultCode(),
                    "查询号源失败，错误信息：" + timeResponse.getResultMessage() + "！");
            return response;
        }

        List<RegisterDoctorTimeVoResponse> timeVoResponses = JsonUtils.parseObject(timeResponse.getResult(), List.class);
        if (CollectionUtils.isEmpty(timeVoResponses)) {
            response.setResultCodeAndMessage("6002", "暂无分时信息！");
            return response;
        } else {
            response.setResultCodeAndMessage("0","成功");
            response.setResult(JsonUtils.toJsonString(timeVoResponses));
        }
        return response;
    }




    /**
     * 测试服务器的问题 yyt.register.reg.doctor.test
     * @param data
     * @param sessionId
     * @return
     */
    public Response testRegDoctor(String data, String sessionId) {
        Response response=new Response();
        response.setResultCodeAndMessage("0","测试");
        logger.info("开始测试");

        Map<String, String> maps = JsonUtils.parseObject(data, Map.class);
        int count=Integer.valueOf(maps.get("count")).intValue();
        long beginTime =0;
        long endTime=0;
        for(int i=0;i<count;i++){
            beginTime=System.currentTimeMillis();
            String findDoctor = "{\"code\":\"0201\",\"hospitalCode\":\"stszxyy\"}";
            Response doctorResponse = BaseService.callHumpFromInternal("yyt.base.doctor.find", findDoctor);
            endTime=System.currentTimeMillis();
            logger.info("测试服务器的问题->查询接口：yyt.base.doctor.find，请求开始时间："+beginTime+",收到返回时间:"+endTime+",耗时:"+(endTime-beginTime)+"ms，收到返回:"+ doctorResponse.getResult());
        }

        logger.info("结束测试");
        return response;
    }

}
